unit smUtils;

interface

  function BoundB(const Value, MinValue, MaxValue: Byte): Byte; inline;
  function BoundW(const Value, MinValue, MaxValue: Word): Word; inline;
  function BoundI(const Value, MinValue, MaxValue: Integer): Integer; inline;
  function AddBoundMaxB(const Value, Addition, MaxValue: Byte): Byte; inline;
  function SubBoundMinB(const Value, Subtraction, MinValue: Byte): Byte; inline;
  function MinOfB(const A, B: Byte): Byte; inline;
  function MinOfW(const A, B: Word): Word; inline;
  function MaxOfB(const A, B: Byte): Byte; inline;
  function MaxOfW(const A, B: Word): Word; inline;

  function IfThenS(const Expression: Boolean;
    const ATrue, AFalse: String): String; inline;

  function CaseC(const Value: Byte;
    const Args: array of Cardinal): Cardinal;

  function ColorBrighten(const Value: Cardinal;
    const Aspect: Byte): Cardinal; inline;

implementation

function BoundB;
begin
  if Value <= MinValue then
    Result := MinValue

  else if Value >= MaxValue then
    Result := MaxValue

  else
    Result := Value;
end;

function BoundW;
begin
  if Value <= MinValue then
    Result := MinValue

  else if Value >= MaxValue then
    Result := MaxValue

  else
    Result := Value;
end;

function BoundI;
begin
  if Value <= MinValue then
    Result := MinValue

  else if Value >= MaxValue then
    Result := MaxValue

  else
    Result := Value;
end;

function AddBoundMaxB;
var
  Sum: Word;
begin
  Sum := Value + Addition;
  if Sum > Word(MaxValue) then
    Result := MaxValue
  else
    Result := Byte(Sum);
end;

function SubBoundMinB;
var
  Sum: SmallInt;
begin
  Sum := Value - Subtraction;
  if Sum < SmallInt(MinValue) then
    Result := MinValue
  else
    Result := Byte(Sum);
end;

function MinOfB;
begin
  if A <= B then
    Result := A
  else
    Result := B;
end;

function MinOfW;
begin
  if A <= B then
    Result := A
  else
    Result := B;
end;

function MaxOfB;
begin
  if A >= B then
    Result := A
  else
    Result := B;
end;

function MaxOfW;
begin
  if A >= B then
    Result := A
  else
    Result := B;
end;

function IfThenS;
begin
  if Expression then
    Result := ATrue
  else
    Result := AFalse;
end;

function CaseC;
begin
{$R-}
  Result := Args[BoundB(Value, Low(Args), High(Args))];
{$R+}
end;

function ColorBrighten;
begin
{$R-}
  Result := (
      Value and $FF000000 // full alpha
      or
      AddBoundMaxB(Value shr 16, Aspect, $FF) shl 16 // brightened red
      or
      AddBoundMaxB(Value shr 8, Aspect, $FF) shl 8   // green
      or
      AddBoundMaxB(Value, Aspect, $FF)               // blue
    );
{$R+}
end;

end.
